package thoven.achievement.net.ideapluginachievement.service

import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import thoven.achievement.net.ideapluginachievement.model.Achievement
import thoven.achievement.net.ideapluginachievement.model.CodeStats
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.YearMonth
import java.time.format.DateTimeFormatter
import java.time.temporal.TemporalAdjusters
import java.util.*

/**
 * 报告类型
 */
enum class ReportType {
    DAILY,  // 日报
    WEEKLY, // 周报
    MONTHLY // 月报
}

/**
 * 报告生成服务（简化版HTML，Swing兼容）
 */
@Service(Service.Level.PROJECT)
class ReportGeneratorService(private val project: Project) {
    
    private val dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日")
    private val weekdayFormatter = DateTimeFormatter.ofPattern("E", Locale.CHINESE)
    
    /**
     * 生成报告
     */
    fun generateReport(type: ReportType): String {
        val codeStatsService = project.service<CodeStatsService>()
        
        return when (type) {
            ReportType.DAILY -> generateDailyReport(codeStatsService)
            ReportType.WEEKLY -> generateWeeklyReport(codeStatsService)
            ReportType.MONTHLY -> generateMonthlyReport(codeStatsService)
        }
    }
    
    /**
     * 生成日报（简化版）
     */
    private fun generateDailyReport(codeStatsService: CodeStatsService): String {
        try {
            val today = LocalDate.now()
            val todayStats = codeStatsService.getStatsByDate(today)
            val todayAchievements = codeStatsService.getAchievementsByDate(today)
            val aggregatedStats = codeStatsService.getAggregatedStats()
            val consecutiveDays = codeStatsService.getConsecutiveDays()
            
            // 获取今日洞察
            val insightService = InsightService.getInstance(project)
            val todayInsights = insightService.generateTodayInsights()
            
            val totalAdded = todayStats.sumOf { it.addedLines }
            val totalDeleted = todayStats.sumOf { it.deletedLines }
            val netLines = totalAdded - totalDeleted
            
            return buildString {
                append("<html><body>")
                append("<h2>📊 编码日报</h2>")
                append("<p>${today.format(dateFormatter)} ${today.format(weekdayFormatter)}</p>")
                
                if (consecutiveDays > 1) {
                    append("<p>🔥 已连续编码 <b>$consecutiveDays</b> 天</p>")
                }
                
                // 添加智能洞察模块
                if (todayInsights.isNotEmpty()) {
                    append("<hr>")
                    append("<h3>💡 智能洞察</h3>")
                    todayInsights.forEach { insight ->
                        append("<p>${insight.icon} <b>${insight.title}</b>: ${insight.description}</p>")
                    }
                }
                
                append("<hr>")
                append("<h3>📈 今日编码统计</h3>")
                append("<p>")
                append("新增代码行数: <font color='green'><b>$totalAdded</b></font><br>")
                append("删除代码行数: <font color='red'><b>$totalDeleted</b></font><br>")
                append("净增代码行数: <b>$netLines</b>")
                append("</p>")
                
                if (todayStats.isNotEmpty()) {
                    append("<p><b>语言分布:</b></p>")
                    todayStats.sortedByDescending { it.addedLines }.forEach { stat ->
                        val percentage = if (totalAdded > 0) (stat.addedLines.toDouble() / totalAdded * 100).toInt() else 0
                        append("<p>&nbsp;&nbsp;• ${stat.language}: ${stat.addedLines}行 ($percentage%)</p>")
                    }
                }
                
                if (todayAchievements.isNotEmpty()) {
                    append("<hr>")
                    append("<h3>🏆 今日解锁成就</h3>")
                    todayAchievements.forEach { achievement ->
                        append("<p>• <b>${achievement.getName()}</b>: ${achievement.getDescription()}</p>")
                    }
                }
                
                append("<hr>")
                append("<h3>🚀 总体进度</h3>")
                append("<p>")
                append("累计新增行数: <b>${aggregatedStats.totalAdded}</b><br>")
                append("累计删除行数: <b>${aggregatedStats.totalDeleted}</b><br>")
                append("累计净增行数: <b>${aggregatedStats.totalNet}</b>")
                append("</p>")
                
                append("<hr>")
                append("<p><i>${getRandomCodingQuote()}</i></p>")
                append("</body></html>")
            }
        } catch (e: Exception) {
            return "<html><body><h2>📊 编码日报</h2><p>暂无统计数据或生成报告时出错。</p><p><font color='red'>错误信息: ${e.message ?: e.javaClass.simpleName}</font></p></body></html>"
        }
    }
    
    /**
     * 生成周报（简化版）
     */
    private fun generateWeeklyReport(codeStatsService: CodeStatsService): String {
        try {
            val today = LocalDate.now()
            val startOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
            val endOfWeek = today
            
            val weekStats = mutableListOf<CodeStats>()
            val weekAchievements = mutableListOf<Achievement>()
            
            var currentDate = startOfWeek
            while (!currentDate.isAfter(endOfWeek)) {
                weekStats.addAll(codeStatsService.getStatsByDate(currentDate))
                weekAchievements.addAll(codeStatsService.getAchievementsByDate(currentDate))
                currentDate = currentDate.plusDays(1)
            }
            
            val totalAdded = weekStats.sumOf { it.addedLines }
            val totalDeleted = weekStats.sumOf { it.deletedLines }
            val netLines = totalAdded - totalDeleted
            
            val daysInReport = startOfWeek.until(endOfWeek).days + 1
            val dailyAvgAdded = if (daysInReport > 0) totalAdded / daysInReport else 0
            
            // 获取本周洞察
            val insightService = InsightService.getInstance(project)
            val weeklyInsights = insightService.generateWeeklyInsights()
            
            return buildString {
                append("<html><body>")
                append("<h2>📊 编码周报</h2>")
                append("<p>${startOfWeek.format(dateFormatter)} 至 ${endOfWeek.format(dateFormatter)}</p>")
                
                // 添加智能洞察模块
                if (weeklyInsights.isNotEmpty()) {
                    append("<hr>")
                    append("<h3>💡 智能洞察</h3>")
                    weeklyInsights.forEach { insight ->
                        append("<p>${insight.icon} <b>${insight.title}</b>: ${insight.description}</p>")
                    }
                }
                
                append("<hr>")
                append("<h3>📈 本周编码统计</h3>")
                append("<p>")
                append("新增代码行数: <font color='green'><b>$totalAdded</b></font><br>")
                append("删除代码行数: <font color='red'><b>$totalDeleted</b></font><br>")
                append("净增代码行数: <b>$netLines</b><br>")
                append("日均新增: <b>$dailyAvgAdded</b> 行")
                append("</p>")
                
                if (weekStats.isNotEmpty()) {
                    append("<p><b>语言分布:</b></p>")
                    weekStats.groupBy { it.language }
                        .mapValues { entry -> entry.value.sumOf { it.addedLines } }
                        .entries.sortedByDescending { it.value }
                        .forEach { (language, lines) ->
                            val percentage = if (totalAdded > 0) (lines.toDouble() / totalAdded * 100).toInt() else 0
                            append("<p>&nbsp;&nbsp;• $language: ${lines}行 ($percentage%)</p>")
                        }
                }
                
                if (weekAchievements.isNotEmpty()) {
                    append("<hr>")
                    append("<h3>🏆 本周解锁成就</h3>")
                    weekAchievements.forEach { achievement ->
                        append("<p>• <b>${achievement.getName()}</b>: ${achievement.getDescription()}</p>")
                    }
                }
                
                append("<hr>")
                append("<h3>📝 本周总结</h3>")
                append("<p>${generateWeeklySummary(totalAdded, totalDeleted, weekAchievements.size)}</p>")
                
                append("<hr>")
                append("<p><i>${getRandomCodingQuote()}</i></p>")
                append("</body></html>")
            }
        } catch (e: Exception) {
            return "<html><body><h2>📊 编码周报</h2><p>暂无统计数据或生成报告时出错。</p><p><font color='red'>错误信息: ${e.message ?: e.javaClass.simpleName}</font></p></body></html>"
        }
    }
    
    /**
     * 生成月报（简化版）
     */
    private fun generateMonthlyReport(codeStatsService: CodeStatsService): String {
        try {
            val today = LocalDate.now()
            val yearMonth = YearMonth.from(today)
            val startOfMonth = yearMonth.atDay(1)
            val endOfMonth = if (today.isBefore(yearMonth.atEndOfMonth())) today else yearMonth.atEndOfMonth()
            
            val monthStats = mutableListOf<CodeStats>()
            val monthAchievements = mutableListOf<Achievement>()
            
            var currentDate = startOfMonth
            while (!currentDate.isAfter(endOfMonth)) {
                monthStats.addAll(codeStatsService.getStatsByDate(currentDate))
                monthAchievements.addAll(codeStatsService.getAchievementsByDate(currentDate))
                currentDate = currentDate.plusDays(1)
            }
            
            val totalAdded = monthStats.sumOf { it.addedLines }
            val totalDeleted = monthStats.sumOf { it.deletedLines }
            val netLines = totalAdded - totalDeleted
            
            val activeDays = monthStats.map { it.date }.distinct().count()
            val totalDays = startOfMonth.until(endOfMonth).days + 1
            val activeRate = if (totalDays > 0) (activeDays.toDouble() / totalDays * 100).toInt() else 0
            val dailyAvgAdded = if (activeDays > 0) totalAdded / activeDays else 0
            
            // 获取本月洞察
            val insightService = InsightService.getInstance(project)
            val monthlyInsights = insightService.generateMonthlyInsights()
            
            return buildString {
                append("<html><body>")
                append("<h2>📊 编码月报</h2>")
                append("<p>${yearMonth.year}年${yearMonth.monthValue}月</p>")
                
                // 添加智能洞察模块
                if (monthlyInsights.isNotEmpty()) {
                    append("<hr>")
                    append("<h3>💡 智能洞察</h3>")
                    monthlyInsights.forEach { insight ->
                        append("<p>${insight.icon} <b>${insight.title}</b>: ${insight.description}</p>")
                    }
                }
                
                append("<hr>")
                append("<h3>📈 本月编码统计</h3>")
                append("<p>")
                append("新增代码行数: <font color='green'><b>$totalAdded</b></font><br>")
                append("删除代码行数: <font color='red'><b>$totalDeleted</b></font><br>")
                append("净增代码行数: <b>$netLines</b><br>")
                append("活跃天数: <b>$activeDays</b> / $totalDays 天 ($activeRate%)<br>")
                append("日均新增: <b>$dailyAvgAdded</b> 行")
                append("</p>")
                
                if (monthStats.isNotEmpty()) {
                    append("<p><b>语言分布:</b></p>")
                    monthStats.groupBy { it.language }
                        .mapValues { entry -> entry.value.sumOf { it.addedLines } }
                        .entries.sortedByDescending { it.value }
                        .forEach { (language, lines) ->
                            val percentage = if (totalAdded > 0) (lines.toDouble() / totalAdded * 100).toInt() else 0
                            append("<p>&nbsp;&nbsp;• $language: ${lines}行 ($percentage%)</p>")
                        }
                }
                
                if (monthAchievements.isNotEmpty()) {
                    append("<hr>")
                    append("<h3>🏆 本月解锁成就</h3>")
                    monthAchievements.forEach { achievement ->
                        append("<p>• <b>${achievement.getName()}</b>: ${achievement.getDescription()}</p>")
                    }
                }
                
                append("<hr>")
                append("<h3>📝 本月总结</h3>")
                append("<p>${generateMonthlySummary(totalAdded, totalDeleted, activeDays, totalDays, monthAchievements.size)}</p>")
                
                append("<hr>")
                append("<p><i>${getRandomCodingQuote()}</i></p>")
                append("</body></html>")
            }
        } catch (e: Exception) {
            return "<html><body><h2>📊 编码月报</h2><p>暂无统计数据或生成报告时出错。</p><p><font color='red'>错误信息: ${e.message ?: e.javaClass.simpleName}</font></p></body></html>"
        }
    }
    
    /**
     * 生成周总结
     */
    private fun generateWeeklySummary(addedLines: Int, deletedLines: Int, achievementsCount: Int): String {
        val summaries = listOf(
            "本周共编写了 <b>$addedLines</b> 行代码，删除了 <b>$deletedLines</b> 行代码，解锁了 <b>$achievementsCount</b> 个成就。继续保持这样的节奏，你的代码将越来越精炼！",
            "这周你贡献了 <b>$addedLines</b> 行新代码，优化删除了 <b>$deletedLines</b> 行，同时解锁了 <b>$achievementsCount</b> 个成就。代码质量和数量都在提升，继续加油！",
            "本周编码成果：<b>$addedLines</b> 行新增，<b>$deletedLines</b> 行删除，<b>$achievementsCount</b> 个成就。每一行代码都是进步，每一次删除都是优化！"
        )
        return summaries.randomOrNull() ?: summaries.firstOrNull() ?: "继续加油编码！"
    }
    
    /**
     * 生成月总结
     */
    private fun generateMonthlySummary(addedLines: Int, deletedLines: Int, activeDays: Int, totalDays: Int, achievementsCount: Int): String {
        val activeRate = if (totalDays > 0) (activeDays.toDouble() / totalDays * 100).toInt() else 0
        
        val summaries = listOf(
            "本月共编写了 <b>$addedLines</b> 行代码，删除了 <b>$deletedLines</b> 行代码，活跃了 <b>$activeDays</b> 天（${activeRate}%），解锁了 <b>$achievementsCount</b> 个成就。这是一个充实的月份，你的努力将转化为项目的进步！",
            "月度编码报告：新增 <b>$addedLines</b> 行，删除 <b>$deletedLines</b> 行，活跃 <b>$activeDays/$totalDays</b> 天，解锁 <b>$achievementsCount</b> 个成就。代码的增减之间，是你不断精进的技艺！",
            "这个月你贡献了 <b>$addedLines</b> 行代码，优化删除了 <b>$deletedLines</b> 行，有 <b>$activeDays</b> 天（${activeRate}%）活跃编码，收获了 <b>$achievementsCount</b> 个成就。持之以恒，终将成就非凡！"
        )
        return summaries.randomOrNull() ?: summaries.firstOrNull() ?: "继续加油编码！"
    }
    
    /**
     * 获取随机编码格言
     */
    private fun getRandomCodingQuote(): String {
        val quotes = listOf(
            "代码就像幽默，如果你需要解释它，那它可能不太好。",
            "任何傻瓜都能写出计算机能理解的代码，优秀的程序员能写出人能理解的代码。",
            "调试代码比写代码难两倍，所以如果你写代码时尽可能聪明，那么你调试时就会聪明不足以解决问题。",
            "程序员的三大美德：懒惰、急躁和傲慢。",
            "编程不是关于你知道什么，而是关于你能解决什么问题。",
            "代码是写给人看的，只是顺便能在机器上运行。",
            "最好的代码是没有代码，因为你不需要维护它。",
            "优秀的代码是它自己最好的文档。",
            "编程的艺术不在于增加代码，而在于减少代码。",
            "今天的代码是明天的技术债。"
        )
        return quotes.randomOrNull() ?: quotes.firstOrNull() ?: "继续加油编码！"
    }
    
    companion object {
        fun getInstance(project: Project): ReportGeneratorService = project.service()
    }
}
